package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * ClassName: DishServiceImpl
 * Package: com.sky.service.impl
 * Description:
 *
 * @Author JJQ
 * @create 2024/3/26 0026 23:09
 * @Version 1.0
 */
@Service
public class DishServiceImpl implements DishService {

    private final DishMapper dishMapper;
    private final DishFlavorMapper dishFlavorMapper;
    private final SetmealDishMapper setmealDishMapper;
    private final RedisTemplate redisTemplate;

    public DishServiceImpl(
            DishMapper dishMapper,
            DishFlavorMapper dishFlavorMapper,
            SetmealDishMapper setmealDishMapper,
            RedisTemplate redisTemplate
    ) {
        this.dishMapper = dishMapper;
        this.dishFlavorMapper = dishFlavorMapper;
        this.setmealDishMapper = setmealDishMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    @Transactional
    public void saveWithFavor(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dishMapper.saveWithFavor(dish);

        List<DishFlavor> list = dishDTO.getFlavors();
        if (!list.isEmpty()) {
            list.forEach(el -> el.setDishId(dish.getId()));
            dishFlavorMapper.insert(list);
        }
        cleanCache("dish_" + dishDTO.getCategoryId());
    }

    @Override
    @Transactional
    public void updateWithFavor(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dishMapper.update(dish);

        List<DishFlavor> list = dishDTO.getFlavors();
        if (!list.isEmpty()) {
            dishFlavorMapper.deleteBatch(dish.getId());

            list.forEach(el -> el.setDishId(dish.getId()));
            dishFlavorMapper.insert(list);
        }
        cleanCache("dish_" + dish.getCategoryId());
    }

    @Override
    public void deleteWithFavor(List<Long> ids) {
        // 查询是否有开启状态的菜品
        if(dishMapper.isOnSale(ids) > 0){
            throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
        }
        //是否有关联套餐
        if(setmealDishMapper.isRelatedDish(ids) > 0) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }
        dishMapper.deleteByIds(ids);

        cleanCache("dish_*");
    }

    @Override
    public DishVO getById(Long id) {
        Dish dish = dishMapper.getById(id);
        List<DishFlavor> dishFlavors = dishFlavorMapper.getMany(dish.getId());
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        dishVO.setFlavors(dishFlavors);
        return dishVO;
    }

    @Override
    public PageResult page(DishPageQueryDTO queryDTO) {
        PageHelper.startPage(queryDTO.getPage(), queryDTO.getPageSize());

        Page<DishVO> page = dishMapper.getPage(queryDTO);

        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public List<DishVO> list(Long categoryId) {

        List<DishVO> list = dishMapper.list(categoryId, StatusConstant.ENABLE);
        list.forEach(dish -> dish.setFlavors(dishFlavorMapper.getMany(categoryId)));
        return list;
    }

    @Override
    public void startOrStop(Integer status, Long id) {
        dishMapper.status(status, id);
    }

    private void cleanCache(String pattern) {
        Set<String> keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

}
